/**
 * @file wa_slider.c
 *
 */

 /*********************
 *      INCLUDES
 *********************/
#include "wa_conf.h"
#if USE_WA_SLIDER != 0
#include "wa_slider.h"

 /*********************
 *      DEFINES
 *********************/

 /**********************
 *      TYPEDEFS
 **********************/

 /**********************
 *  STATIC PROTOTYPES
 **********************/
static wa_obj_callback ancestor_callback;
static void wa_slider_callback(wa_sign* sign);
/**********************
 *  STATIC VARIABLES
 **********************/


 /**********************
 *      MACROS
 **********************/

 /**********************
 *   GLOBAL FUNCTIONS
 **********************/
 /**
 * slider module init
 */
void wa_slider_module_init(void)
{
}

/**
* create a slider
* @param par
* @return slider obj
*/
wa_obj* wa_slider_create(wa_obj* par)
{
	wa_obj* new_slider;
	wa_slider_ext* slider_ext;

	new_slider = wa_obj_create(par, NULL);
	if (new_slider == NULL)
	{
		return new_slider;
	}

	if (ancestor_callback == NULL)
	{
		ancestor_callback = wa_obj_get_callback(new_slider);
	}
	slider_ext = wa_obj_malloc_ext_attr(new_slider, sizeof(wa_slider_ext));
	if (slider_ext == NULL)
	{
		return NULL;
	}

	slider_ext->dir = WA_SLIDER_DIR_LEFT;
	slider_ext->min_value = 0;
	slider_ext->max_value = 100;
	slider_ext->value = 50;
	slider_ext->fore_color = WA_COLOR_FOREGROUND;
	slider_ext->back_color = WA_COLOR_BACKGROUND;
	slider_ext->slider_width = 1;
	slider_ext->twig_width = 1;

	wa_obj_set_callback(new_slider, wa_slider_callback);

	return new_slider;
}

/**
* slider set direction
* @param slider
* @param direction
*/
void wa_slider_set_direction(wa_obj* slider, wa_slider_direction direction)
{
	wa_slider_ext* ext;
	ext = wa_obj_get_ext_attr(slider);
	ext->dir = direction;
	wa_obj_invalidate(slider);
}

/**
* slider set min and max value
* @param slider
* @param min
* @param max
*/
void wa_slider_set_limit_value(wa_obj* slider, int32_t min, int32_t max)
{
	wa_slider_ext* ext;
	ext = wa_obj_get_ext_attr(slider);
	ext->min_value = min;
	ext->max_value = max;
	wa_obj_invalidate(slider);
}

/**
* slider set value
* @param slider
* @param value
*/
void wa_slider_set_value(wa_obj* slider, int32_t value)
{
	wa_slider_ext* ext;
	ext = wa_obj_get_ext_attr(slider);
	if (value >= ext->max_value)
	{
		value = ext->max_value;
	}
	if (value <= ext->min_value)
	{
		value = ext->min_value;
	}
	if (value == ext->value)
	{
		return;
	}
	ext->value = value;
	wa_wm_notify_parent(slider, WA_SIGNAL_NOTIFY_VALUE_CHANGED);
	wa_obj_invalidate(slider);
}

/**
* slider fore color
* @param slider
* @param fore color
*/
void wa_slider_set_fore_color(wa_obj* slider, wa_gui_color color)
{
	wa_slider_ext* ext;
	ext = wa_obj_get_ext_attr(slider);
	ext->fore_color = color;
	wa_obj_invalidate(slider);
}

/**
* slider back color
* @param slider
* @param back color
*/
void wa_slider_set_back_color(wa_obj* slider, wa_gui_color color)
{
	wa_slider_ext* ext;
	ext = wa_obj_get_ext_attr(slider);
	ext->back_color = color;
	wa_obj_invalidate(slider);
}

/**
* slider slider width
* @param slider
* @param slider width
*/
void wa_slider_set_slider_width(wa_obj* slider, uint32_t slider_width)
{
	wa_slider_ext* ext;
	ext = wa_obj_get_ext_attr(slider);
	ext->slider_width = slider_width;
	wa_obj_invalidate(slider);
}

/**
* slider twig width
* @param slider
* @param twig width
*/
void wa_slider_set_twig_width(wa_obj* slider, uint32_t twig_width)
{
	wa_slider_ext* ext;
	ext = wa_obj_get_ext_attr(slider);
	ext->twig_width = twig_width;
	wa_obj_invalidate(slider);
}

/**
* slider get direction
* @param slider
* @return direction
*/
wa_slider_direction wa_slider_get_direction(wa_obj* slider)
{
	wa_slider_ext* ext;
	ext = wa_obj_get_ext_attr(slider);
	return ext->dir;
}

/**
* slider get value
* @param slider
* @return value
*/
int32_t wa_slider_get_value(wa_obj* slider)
{
	wa_slider_ext* ext;
	ext = wa_obj_get_ext_attr(slider);
	return ext->value;
}

/**
* slider get fore color
* @param slider
* @return fore color
*/
wa_gui_color wa_slider_get_fore_color(wa_obj* slider)
{
	wa_slider_ext* ext;
	ext = wa_obj_get_ext_attr(slider);
	return ext->fore_color;
}

/**
* slider get back color
* @param slider
* @return back color
*/
wa_gui_color wa_slider_get_back_color(wa_obj* slider)
{
	wa_slider_ext* ext;
	ext = wa_obj_get_ext_attr(slider);
	return ext->back_color;
}

/**
* slider get slider width
* @param slider
* @return slider width
*/
uint32_t wa_slider_get_slider_width(wa_obj* slider)
{
	wa_slider_ext* ext;
	ext = wa_obj_get_ext_attr(slider);
	return ext->slider_width;
}

/**
* slider get twig width
* @param slider
* @return twig width
*/
uint32_t wa_slider_get_twig_width(wa_obj* slider)
{
	wa_slider_ext* ext;
	ext = wa_obj_get_ext_attr(slider);
	return ext->twig_width;
}

/**********************
*   STATIC FUNCTIONS
**********************/
/**
* slider redraw functions
* @param obj
*/
static void _Paint(wa_obj* obj)
{
	int w, h;
	wa_slider_ext* ext;
	ext = wa_obj_get_ext_attr(obj);
	w = wa_obj_get_width(obj);
	h = wa_obj_get_height(obj);
	wa_mask_fillrect(obj->rect.x1, obj->rect.y1,
					w,h,
					&(obj->redraw_rect),
					ext->back_color);
	if (ext->dir == WA_SLIDER_DIR_UP)
	{
		uint32_t twig_width;
		uint32_t twig_x, twig_y;
		uint32_t slider_pos;
		twig_width = ((((w + ext->twig_width) % 2) == 1) ? 1 : 0) + ext->twig_width;
		twig_x = obj->rect.x1 + (w - twig_width) / 2;
		twig_y = obj->rect.y1;
		wa_mask_fillrect(twig_x, twig_y, twig_width, h, &(obj->redraw_rect), ext->fore_color);
		slider_pos = (h - ext->slider_width) * (ext->value - ext->min_value) / (ext->max_value - ext->min_value);
		wa_mask_fillrect(obj->rect.x1, obj->rect.y1 + slider_pos, w, ext->slider_width, &(obj->redraw_rect), ext->fore_color);
	}
	else if (ext->dir == WA_SLIDER_DIR_DOWN)
	{
		uint32_t twig_width;
		uint32_t twig_x, twig_y;
		uint32_t slider_pos;
		twig_width = ((((w + ext->twig_width) % 2) == 1) ? 1 : 0) + ext->twig_width;
		twig_x = obj->rect.x1 + (w - twig_width) / 2;
		twig_y = obj->rect.y1;
		wa_mask_fillrect(twig_x, twig_y, twig_width, h, &(obj->redraw_rect), ext->fore_color);
		slider_pos = h - (h - ext->slider_width) * (ext->value - ext->min_value) / (ext->max_value - ext->min_value) - ext->slider_width;
		wa_mask_fillrect(obj->rect.x1, obj->rect.y1 + slider_pos, w, ext->slider_width, &(obj->redraw_rect), ext->fore_color);
	}
	else if (ext->dir == WA_SLIDER_DIR_LEFT)
	{
		uint32_t twig_width;
		uint32_t twig_x, twig_y;
		uint32_t slider_pos;
		twig_width = ((((h + ext->twig_width) % 2) == 1) ? 1 : 0) + ext->twig_width;
		twig_x = obj->rect.x1;
		twig_y = obj->rect.y1 + (h - twig_width) / 2;
		wa_mask_fillrect(twig_x, twig_y, w, twig_width, &(obj->redraw_rect), ext->fore_color);
		slider_pos = (w - ext->slider_width) * (ext->value - ext->min_value) / (ext->max_value - ext->min_value);
		wa_mask_fillrect(obj->rect.x1 + slider_pos, obj->rect.y1, ext->slider_width, h, &(obj->redraw_rect), ext->fore_color);
	}
	else if (ext->dir == WA_SLIDER_DIR_RIGHT)
	{
		uint32_t twig_width;
		uint32_t twig_x, twig_y;
		uint32_t slider_pos;
		twig_width = ((((h + ext->twig_width) % 2) == 1) ? 1 : 0) + ext->twig_width;
		twig_x = obj->rect.x1;
		twig_y = obj->rect.y1 + (h - twig_width) / 2;
		wa_mask_fillrect(twig_x, twig_y, w, twig_width, &(obj->redraw_rect), ext->fore_color);
		slider_pos = w - (w - ext->slider_width) * (ext->value - ext->min_value) / (ext->max_value - ext->min_value) - ext->slider_width;
		wa_mask_fillrect(obj->rect.x1 + slider_pos, obj->rect.y1, ext->slider_width, h, &(obj->redraw_rect), ext->fore_color);
	}
}

/**
 * slider obj delete function
 * @param obj
 */
static void _Delete(wa_obj* obj)
{
}

/**
 * slider obj callback function
 * @param sign
 */
static void wa_slider_callback(wa_sign* sign)
{
	int sign_id;
	wa_obj* obj;

	ancestor_callback(sign);
	sign_id = sign->sign_id;
	obj = sign->obj_dst;

	switch (sign_id)
	{
		case WA_SIGNAL_PAINT:
		{
			_Paint(obj);
			break;
		}
		case WA_SIGNAL_DELETE:
		{
			_Delete(obj);
			break;
		}
		default:
		{
			break;
		}
	}
}

#endif
